﻿using System;
using System.Linq;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Framework.Client;
using Microsoft.LightSwitch.Presentation;
using Microsoft.LightSwitch.Presentation.Extensions;
using System.Xml.Linq;
using Microsoft.LightSwitch.Threading;
using System.Windows.Browser;

namespace LightSwitchApplication
{
    public partial class SalesOrderDetail
    {
        partial void SalesOrder_Loaded(bool succeeded)
        {
            // Write your code here.
            this.SetDisplayNameFromEntity(this.SalesOrder);
        }

        partial void SalesOrder_Changed()
        {
            // Write your code here.
            this.SetDisplayNameFromEntity(this.SalesOrder);
        }

        partial void SalesOrderDetail_Saved()
        {
            this.SetDisplayNameFromEntity(this.SalesOrder);
        }

        partial void SalesOrderDetail_Activated()
        {
            this.DisplayName = this.SalesOrderId.ToString() + " (Торговый заказ)";
            try
            {
                this.FindControl("Save").IsEnabled = (this.Application.User.HasPermission(Permissions.CanEditSalesOrder)
                        || this.Application.User.HasPermission(Permissions.CanManageMySalesOrder)
                    );
            }
            catch (Exception)
            {
            }
        }

        partial void SalesOrderDetail_Saving(ref bool handled)
        {
            // Write your code here.
            //foreach (var item in this.SalesOrder.SalesOrderItems)
            //{
            //    foreach (var itemRecipe in item.ItemRecipes)
            //    {
            //        if (itemRecipe.RecipeGroup == null)
            //        {
            //            itemRecipe.Delete();
            //        }
            //    }
            //}
            foreach (var item in this.SalesOrder.SalesOrderItems)
	        {
                item.ItemRecipeCode = ""; //recalculate recipe code
	        }
            //посчитать цену, учесть скидку  клиента. сделать сумму
            RefreshPrices();
        }

        public void RefreshPrices()
        {
            foreach (var item in this.SalesOrder.SalesOrderItems)
            {
                item.ItemPrice = 0;
                foreach (var itemRecipe in item.ItemRecipes)
	            {
                    if (itemRecipe.RecipeDependency != null && itemRecipe.RecipeDependency.ChildProduct != null)
                        item.ItemPrice += GetPrice(itemRecipe.RecipeDependency.ChildProduct);
	            }
            }
        }

        private decimal GetPrice(Product product)
        {
            decimal result = 0;
            if (product != null)
            {
                var productPrice = product.ProductPrices.Where(pr => pr.PriceDate <= this.SalesOrder.OrderDate).OrderBy(pr => pr.PriceDate).LastOrDefault();
                if (productPrice != null)
                    result = productPrice.Price;
            }

            return result;
        }

        partial void ShowAuditHistory_Execute()
        {
            this.Application.ShowAuditLogHistory("Торговые заказы", this.SalesOrder.Id);
        }


        partial void AcceptOrder_CanExecute(ref bool result)
        {
            string currentStateCode = GetCurrentStateCode();
            result = ((currentStateCode == "" || currentStateCode == "02" || currentStateCode == "03" || currentStateCode == "04")
                && this.SalesOrder.OrderCount>0);
        }
        partial void AcceptOrder_Execute()
        {
            ChangeStatus("01");
        }

        partial void PostponeOrder_CanExecute(ref bool result)
        {
            //если заказ уже принят, то отложить заказ возможно
            result = (GetCurrentStateCode() == "01");
        }
        partial void PostponeOrder_Execute()
        {
            ChangeStatus("03");
        }


        partial void CancelOrder_CanExecute(ref bool result)
        {
            //если заказ уже принят или отложен или оплачен, то отменить заказ возможно
            string currentStateCode = GetCurrentStateCode();
            result = (currentStateCode == "01" || currentStateCode == "03" || currentStateCode == "04");
        }
        partial void CancelOrder_Execute()
        {
            ChangeStatus("02");
        }


        partial void PayOrder_CanExecute(ref bool result)
        {
            result = (GetCurrentStateCode() == "01" && this.SalesOrder.OrderCount > 0); //документ принят, можно оплатить
        }

        partial void PayOrder_Execute()
        {
            ChangeStatus("04");
        }


        partial void ProduceOrder_CanExecute(ref bool result)
        {
            result = (GetCurrentStateCode() == "04" && this.SalesOrder.OrderCount > 0); //документ оплачен, можно передать в производство
        }
        partial void ProduceOrder_Execute()
        {
            ChangeStatus("05");
        }

        partial void StockOrder_CanExecute(ref bool result)
        {
            result = (GetCurrentStateCode() == "05" && this.SalesOrder.OrderCount > 0); //заказ произведен, можно передать на склад
        }

        partial void StockOrder_Execute()
        {
            ChangeStatus("06");
        }

        partial void DeliverOrder_CanExecute(ref bool result)
        {
            result = (GetCurrentStateCode() == "06"); //заказ произведен, можно доставить
        }
        partial void DeliverOrder_Execute()
        {
            ChangeStatus("07");
        }

        private string GetCurrentStateCode()
        {
            string result = String.Empty;
            DocumentStatus currentStatus = this.SalesOrder.DocumentStatusSet.OrderBy(ss => ss.StatusDate).LastOrDefault();
            if (currentStatus != null && currentStatus.DocumentState != null)
                result = currentStatus.DocumentState.Value;
            return result;
        }

        private void ChangeStatus(string NextCode)
        {
            //NewStateProperties
            if (GetCurrentStateCode() != NextCode)
            {
                SystemParameter newState = this.SalesOrderStates.Where(ss => ss.Value == NextCode).FirstOrDefault();
                if (newState != null)
                {
                    DocumentStatus newStatus = this.SalesOrder.DocumentStatusSet.AddNew();
                    newStatus.StatusDate = DateTime.Now;
                    newStatus.DocumentState = newState;
                    this.OpenModalWindow("DocumentStateList");
                    this.DocumentStatusSet.SelectedItem = newStatus;
                    this.FindControlInCollection("NewStateProperties", this.DocumentStatusSet.SelectedItem).DisplayName = "Новое состояние";
                    this.OpenModalWindow("NewStateProperties", this.DocumentStatusSet.SelectedItem);
                }
            }
        }

        partial void AddNewStateProperties_Execute()
        {
            if (this.DocumentStatusSet.SelectedItem != null)
            {
                this.CloseModalWindow("NewStateProperties", this.DocumentStatusSet.SelectedItem);
                this.FindControlInCollection("NewStateProperties", this.DocumentStatusSet.SelectedItem).IsVisible = false;
            }
            this.CloseModalWindow("DocumentStateList");
            this.Save();
        }

        partial void CancelNewStateProperties_Execute()
        {
            if (this.DocumentStatusSet.SelectedItem != null)
            {
                this.FindControlInCollection("NewStateProperties", this.DocumentStatusSet.SelectedItem).IsVisible = false;
                this.CloseModalWindow("NewStateProperties", this.DocumentStatusSet.SelectedItem);
                this.DocumentStatusSet.RemoveSelected();
            }
            this.CloseModalWindow("DocumentStateList");
        }

        partial void SalesOrderDetail_InitializeDataWorkspace(List<IDataService> saveChangesTo)
        {
        }

        partial void ShowPrintOrder_Execute()
        {
            LoadPrintView();
        }

        private void LoadPrintView()
        {
            if (this.SalesOrder.Id > 0)
            {
                XDocument xDoc = new XDocument(
                        new XDeclaration("1.0", "utf-8", "yes")
                    //xDoc.AddFirst(new XProcessingInstruction("xml-stylesheet", "type='text/xsl' href='SalesOrder.xslt'")
                    );
                XElement xRoot = new XElement("Order",
                            new XAttribute("Id", this.SalesOrder.Id.ToString()),
                            new XAttribute("Date", this.SalesOrder.OrderDate.ToString("g")),
                            new XAttribute("Sum", this.SalesOrder.OrderAmount.ToString("#,#.00#;(#,#.00#)"))
                    );

                var myCompany = this.DataWorkspace.ApplicationData.Customers.Where(c => c.CustomerType.Name == "Моя компания").FirstOrDefault(); //may be need more filters ???
                if (myCompany != null)
                {
                    xRoot.Add(LoadCustomerInfo(myCompany, "MyCompany"));
                }
                if (this.SalesOrder.OrderShop != null)
                {
                    var customer = this.SalesOrder.OrderShop.ShopCustomer;
                    if (customer != null)
                    {
                        xRoot.Add(LoadCustomerInfo(customer, "Customer"));
                    }
                }

                int itemNo = 0;
                foreach (var item in this.SalesOrder.SalesOrderItems.OrderBy(so => so.ItemRecipeCode))
                {
                    itemNo++;
                    XElement itemNode = new XElement("Item",
                            new XAttribute("ItemNo", itemNo.ToString()),
                            new XAttribute("ItemRecipeCode", (item.ItemRecipeCode != null ? item.ItemRecipeCode : "")),
                            new XAttribute("ItemQty", (item.ItemQty == null ? "" : ((decimal)item.ItemQty).ToString("#,#.00#;(#,#.00#)"))),
                            new XAttribute("ItemSum", item.ItemSum.ToString("#,#.00#;(#,#.00#)"))
                        );
                    foreach (var itemRecipe in item.ItemRecipes)
                    {
                        itemNode.Add(AddRecipe(itemRecipe));
                    }
                    xRoot.Add(itemNode);
                }
                xDoc.Add(xRoot);

                string ulrString = string.Format(@"DownloadFile.aspx?OrderId={0}&src={1}", this.SalesOrder.Id.ToString(), Utils.SimpleEncoder(xDoc.ToString()));
                Dispatchers.Main.Invoke(() =>
                {
                    HtmlPage.Window.Navigate(new Uri(ulrString, UriKind.Relative));//, "_new"
                });

                //Microsoft.LightSwitch.Threading.Dispatchers.Main.BeginInvoke(() =>
                //{
                //    System.Text.StringBuilder codeToRun = new System.Text.StringBuilder();
                //    codeToRun.Append("window.open(");
                //    codeToRun.Append("\"");
                //    codeToRun.Append(string.Format("{0}", String.Format(@"DownloadFile.aspx?id={0}&src={1}",
                //        this.SalesOrder.Id.ToString()+".html"
                //        , Utils.SimpleEncoder("<html>Hello World!</html>")))); //GetBaseAddress(), 
                //        //, Utils.SimpleEncoder(root.ToString())))); //GetBaseAddress(), 
                //    codeToRun.Append("\",");
                //    codeToRun.Append("\"");
                //    codeToRun.Append("\",");
                //    codeToRun.Append("\"");
                //    codeToRun.Append("width=680,height=640");
                //    codeToRun.Append(",scrollbars=yes,menubar=no,toolbar=no,resizable=yes");
                //    codeToRun.Append("\");");
                //    try
                //    {
                //        System.Windows.Browser.HtmlPage.Window.Eval(codeToRun.ToString());
                //    }
                //    catch (Exception ex)
                //    {
                //        MessageBox.Show(ex.Message,
                //            "Error", MessageBoxButton.OK);
                //    }
                //});
            }
        }

        private static XElement AddRecipe(SalesOrderItemRecipe itemRecipe)
        {
            return(new XElement("ItemRecipe",
                new XAttribute("ParentGroupName", (itemRecipe.ParentRecipeGroup != null ? itemRecipe.ParentRecipeGroup.ProductGroupName : ""))
                , new XAttribute("ParentProductName", (itemRecipe.ParentRecipeProduct != null ? itemRecipe.ParentRecipeProduct.ProductName : ""))
                , new XAttribute("RecipeGroupName", (itemRecipe.RecipeGroup != null ? itemRecipe.RecipeGroup.ProductGroupName : ""))
                , new XAttribute("RecipeProductName", (itemRecipe.RecipeDependency != null && itemRecipe.RecipeDependency.ChildProduct != null ? itemRecipe.RecipeDependency.ChildProduct.ProductName : ""))
                , new XAttribute("RecipeProductCode", (itemRecipe.RecipeDependency != null && itemRecipe.RecipeDependency.ChildProduct != null && itemRecipe.RecipeDependency.ChildProduct.ProductCode != null ? itemRecipe.RecipeDependency.ChildProduct.ProductCode : ""))
                , new XAttribute("RecipePrice", itemRecipe.RecipePrice.ToString("#,#.00#;(#,#.00#)"))
             ));
        }

        private static XElement LoadCustomerInfo(Customer myCompany, string tagName)
        {
            XElement xMC = new XElement(tagName,
                    new XAttribute("Name", myCompany.CustomerName),
                    new XAttribute("Code", (myCompany.CustomerCode == null ? "" : myCompany.CustomerCode)),
                    new XAttribute("CodeTax", (myCompany.CustomerCodeTax == null ? "" : myCompany.CustomerCodeTax)),
                    new XAttribute("VatNo", (myCompany.CustomerVatNo == null ? "" : myCompany.CustomerVatNo))
                );
            var myCompanyPrimaryContact = myCompany.CustomerContacts.Where(cn => cn.ContactIsPrimary == true).FirstOrDefault();
            if (myCompanyPrimaryContact != null)
            {
                xMC.Add(new XAttribute("Phone", (myCompanyPrimaryContact.ContactPhone == null ? "" : myCompanyPrimaryContact.ContactPhone)));
                xMC.Add(new XAttribute("Email", (myCompanyPrimaryContact.ContactEmail == null ? "" : myCompanyPrimaryContact.ContactEmail)));
                xMC.Add(new XAttribute("Fax", (myCompanyPrimaryContact.ContactFax == null ? "" : myCompanyPrimaryContact.ContactFax)));
            }
            return xMC;
        }

        partial void ShowPrintOrder_CanExecute(ref bool result)
        {
            string currentStateCode = GetCurrentStateCode();
            result = ((currentStateCode == "01" || currentStateCode == "04" || currentStateCode == "05" || currentStateCode == "06" || currentStateCode == "07")
                ); //&& this.SalesOrder.OrderAmount > 0
        }

        //partial void ShowXml_Execute()
        //{
        //    string url = string.Format("ApplicationData.svc/SalesOrders({0})", this.SalesOrder.Id.ToString());
        //    Dispatchers.Main.Invoke(() =>
        //    {
        //        HtmlPage.Window.Navigate(new Uri(url, UriKind.Relative), "_new");
        //    });
        //}


    }
}